package com.lime49.lockcrypt;
import java.net.*;
import java.io.*;
import javax.swing.*;
import org.json.*;

/**
 * A thread which listens for connections on localhost to port 1556 from the Firefox extension
 */
public class FirefoxSocket extends Thread {
    private ServerSocket serverSock = null;
    private FrmMainWindow parent;
    private boolean listening = false;
    
    public FirefoxSocket(FrmMainWindow parent) {
        this.parent = parent;
        ServerSocket sock = null;
        this.setPriority(8);
        try {
            sock = new ServerSocket(1556, 2, InetAddress.getByName("localhost"));
            this.serverSock = sock;
        } catch(Exception ex) {
            javax.swing.JOptionPane.showMessageDialog(null, parent.getLanguage().getString("ERROR")+"#200: "+parent.getLanguage().getString("ERR_STARTFIREFOXSERVER")+": "+ex.getLocalizedMessage(), parent.getLanguage().getString("ERROR"), javax.swing.JOptionPane.INFORMATION_MESSAGE);
        }
    }
    @Override
    public void run() {
        listening = true;
        while(listening) {
            try {
                new SocketWorker(parent, serverSock.accept()).start();
            } catch(Exception ex) { }
        }
    }
    
    public boolean isRunning() {
        return listening;
    }
    
    public void stopServer() {
        listening = false;
        if(serverSock != null) {
            try {
                serverSock.close();
                if(parent.getDebug()) {
                    JOptionPane.showMessageDialog(null, "Stopped firefox server", "Information", javax.swing.JOptionPane.INFORMATION_MESSAGE);
                }
            } catch(Exception ignore) {/**/}
        }
    }
    
    /**
     * Performs the actual work to serve requests from the Firefox extension.
     */
    class SocketWorker extends Thread {
        private FrmMainWindow parent;
        private Socket sock;
        
        public SocketWorker(FrmMainWindow parent, Socket socket) {
            //System.out.println("Started Worker Thread");
            this.parent = parent;
            this.sock = socket;
            this.setPriority(10);
        }
        
        @Override
        public void run() {
            try {
                PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
                BufferedReader in = new BufferedReader(
                                        new InputStreamReader(
                                        sock.getInputStream()));
                StringBuffer buffer = new StringBuffer();
                int c = 0;
                while((c = in.read()) != -1) {
                        if(c == 23)
                            break;
                        buffer.append((char)c);
                }
                try {
                    JSONObject jso = new JSONObject(buffer.toString());
                    String type = jso.getString("type");
                    String response = "";
                    if(type.equals("REQUEST")) {
                        response = parent.findPasswords(jso.getString("URL"));
                    } else if(type.equals("PING")) {
                        response = "PONG";
                    } else if(type.equals("SAVE")) {
                        response = parent.savePassword(jso);
                    } else if(type.equals("NAMEENQUIRY")) {
                        response = parent.findPasswordNames(jso.getString("URL"));
                    } else if(type.equals("EXPORT")) {
                        response = parent.exportToFirefox();
                    } else if(type.equals("IMPORT")) {
                        response = parent.importFromFirefox(jso.getString("accounts"));
                    } else if(type.equals("CHECKIFEXISTS")) {
                        response = parent.checkAccountExists(jso);
                    }
                    System.out.println("Received "+type+" "+buffer.toString()+", Sent to Firefox:"+response);
                    out.print(response);
                } catch(Exception ex) {
                    out.println("Malformed JSON received: "+ex.toString());
                }
                out.close();
                in.close();
                sock.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
